package com.mingqijia.gassafety.job.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mingqijia.gassafety.db.entity.auth.CompanyEntry;
import com.mingqijia.gassafety.db.entity.auth.HierarchyEntry;
import com.mingqijia.gassafety.db.entity.auth.ManagerEntry;
import com.mingqijia.gassafety.db.entity.auth.RoleEntry;
import com.mingqijia.gassafety.db.mapper.auth.CompanyMapper;
import com.mingqijia.gassafety.db.mapper.auth.HierarchyMapper;
import com.mingqijia.gassafety.db.mapper.auth.ManagerMapper;
import com.mingqijia.gassafety.db.mapper.auth.RoleMapper;
import com.mingqijia.gassafety.job.request.ManagerListRequest;
import com.mingqijia.gassafety.job.response.ManagerResponse;
import com.mingqijia.gassafety.job.service.ManagerService;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.enums.RunningState;
import com.mingqijia.gassafety.shared.enums.YesNoEnum;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.shared.utils.MappingTools;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.function.Consumer;

/**
 * <p>
   故障记录 服务类
 * </p>
 *
 * @author guoliang.lao
 * @since 2022-03-04
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ManagerServiceImpl extends ServiceImpl<ManagerMapper, ManagerEntry> implements ManagerService {

    private final CompanyMapper companyMapper;
    private final HierarchyMapper hierarchyMapper;
    private final RoleMapper roleMapper;

    @Override
    public PageUtil<ManagerResponse> list(ManagerListRequest req) {
        LambdaQueryWrapper<ManagerEntry> queryClause = new LambdaQueryWrapper<>();
        if (CollectionUtils.isEmpty(req.getUserId())) {
            Optional.ofNullable(req.getUsername()).ifPresent(
                    username -> queryClause.eq(ManagerEntry::getUsername, username)
            );
            Optional.ofNullable(req.getName()).ifPresent(
                    name -> queryClause.like(ManagerEntry::getName, name)
            );
            Optional.ofNullable(req.getPhone()).ifPresent(
                    phone -> queryClause.eq(ManagerEntry::getPhone, phone)
            );
            if (!CollectionUtils.isEmpty(req.getRoles())) {
                Consumer<LambdaQueryWrapper<ManagerEntry>> consumer = queryWhere -> {
                    int length = req.getRoles().size();
                    for (int index = 0; index < length; index++) {
                        if (index < length - 1) {
                            queryWhere.like(ManagerEntry::getRoleId, req.getRoles().get(index)).or();
                            continue;
                        }
                        queryWhere.like(ManagerEntry::getRoleId, req.getRoles().get(index));
                    }
                };
                queryClause.and(consumer);
            }
            if (Objects.nonNull(req.getState()) && RunningState.NA.getCode() != req.getState()) {
                queryClause.eq(ManagerEntry::getState, req.getState());
            }
            if (!CollectionUtils.isEmpty(req.getHierarchy())) {
                queryClause.like(ManagerEntry::getHierarchy, MappingTools.toRaw(req.getHierarchy()));
            }
            if (!CollectionUtils.isEmpty(req.getDepartment())) {
                queryClause.like(ManagerEntry::getDepartment, MappingTools.toRaw(req.getDepartment()));
            }
        } else {
            queryClause.in(ManagerEntry::getId, req.getUserId());
        }
        queryClause.eq(ManagerEntry::getIsDeleted, YesNoEnum.N.getCode())
                .eq(ManagerEntry::getSpId, req.getSpId())
                .orderByDesc(ManagerEntry::getCreatedAt);
        Page<ManagerEntry> entries = this.page(new Page<>(req.getPage(), req.getPageSize()), queryClause);

        List<ManagerResponse> responses = new ArrayList<>();
        for (ManagerEntry record : entries.getRecords()) {
            ManagerResponse response = new ManagerResponse();
            BeanUtil.copyProperties( record, response );
            // 变换显示中文
            if (StringUtils.hasText(response.getRoleId())) {
                response.setRoleId(buildRoleNames(response.getRoleId()));
            }
            if (StringUtils.hasText(response.getDepartment())) {
                response.setDepartment(buildDepartmentNames(response.getDepartment()));
            }
            if (StringUtils.hasText(response.getHierarchy())) {
                response.setHierarchy(buildCompanyNames(response.getHierarchy()));
            }
            response.setState(Objects.equals(Constants.STR_ONE, response.getState()) ? "激活" : "锁定");
            responses.add(response);
        }
        return PageUtil.init(entries, responses);
    }

    private String buildRoleNames(String raw) {
        List<String> roleIds = MappingTools.fromRaw(raw);
        List<RoleEntry> entries = roleMapper.selectBatchIds(roleIds);
        if (CollectionUtils.isEmpty(entries)) {
            return Constants.STR_EMPTY;
        }
        StringBuilder builder = new StringBuilder();
        entries.forEach(entry -> builder.append(Constants.STR_COMMA).append(entry.getName()));
        return builder.substring(Constants.INT_ONE);
    }

    private String buildDepartmentNames(String raw) {
        List<String> hierarchyIds = MappingTools.fromRaw(raw);
        StringBuilder builder = new StringBuilder();

        HierarchyEntry entry;
        for (String hierarchyId : hierarchyIds) {
            entry = hierarchyMapper.selectById(hierarchyId);
            if (Objects.nonNull(entry)) {
                builder.append(Constants.STR_COMMA).append(entry.getName());
            }
        }
        return builder.substring(Constants.INT_ONE);
    }

    private String buildCompanyNames(String raw) {
        List<String> companyIds = MappingTools.fromRaw(raw);
        List<CompanyEntry> entries = companyMapper.selectBatchIds(companyIds);
        if (CollectionUtils.isEmpty(entries)) {
            return Constants.STR_EMPTY;
        }
        Map<String, String> map = new HashMap<>();
        entries.forEach(item -> map.put(item.getId(), item.getName()));

        StringBuilder builder = new StringBuilder();
        for (String companyId : companyIds) {
            builder.append(Constants.STR_COMMA).append(map.get(companyId));
        }
        return builder.substring(Constants.INT_ONE);
    }
}
